<script setup lang='ts'>
import { ref, onMounted, nextTick } from 'vue'

const list = ref([])
const container = ref(null) // 父容器
const boxHeight = ref([]) // 子元素每列高度

onMounted(async () => { // 基础数据
  for (let i = 0; i < 50; i++) {
    let num = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50]
    const length = Math.floor(Math.random() * 50 + 1)
    num.length = length
    list.value.push(num.join(','))
  }
  await nextTick()
  waterFall()
  window.addEventListener('resize', () => {
    boxHeight.value = []
    waterFall()
  })
})

const waterFall = () => { // 瀑布流
  const content = container.value.children  // 获取所有子元素

  const containerWidth = container.value.offsetWidth // 获取父容器宽度
  const boxWidth = content[0].offsetWidth + 10 * 2// 获取子元素宽度
  const column = Math.floor(containerWidth / boxWidth) // 计算一行可以放多少个子元素

  for (let i = 0; i < content.length; i++) {
    if (i < column) {
      boxHeight.value[i] = content[i].offsetHeight + 10 * 2 // 初始化每列高度
    } else {
      let min = Math.min(...boxHeight.value) // 获取最小高度
      let minIndex = boxHeight.value.indexOf(min) // 获取最小高度的索引

      content[i].style.position = 'absolute'
      content[i].style.top = min + 'px' // 设置子元素top
      content[i].style.left = minIndex * boxWidth + 'px' // 设置子元素left

      boxHeight.value[minIndex] += content[i].offsetHeight + 10 * 2 // 更新最小高度
    }
  }

}

</script>


<template>
  <div class="waterfall" ref="container">
    <div class="box" v-for="(item, index) in list" :key="index">{{ item }}</div>
  </div>
</template>


<style scoped lang="scss">
.waterfall {
  position: relative;
  height: 100%;

  .box {
    float: left;
    padding: 10px;
    margin: 10px;
    width: 200px;
    background-color: #fff;
    border-radius: 5px;
    font-size: 14px;
    color: #333;
    line-height: 1.5;
    transition: all 0.3s ease-in-out;
    box-shadow: 1px 1px 5px rgb(243, 23, 188);
    word-wrap: break-word;

    &:hover {
      background-color: rgb(166, 202, 231);
    }
  }
}
</style>